﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Net;
using System.IO;
using System.Threading;

namespace Common.Controls
{
    /// <summary>
    /// ImageViewer.xaml 的交互逻辑
    /// </summary>
    public partial class ImageViewer : UserControl
    {
        private string source;

        public string Source
        {
            get { return source; }
            set { source = value; }
        }

        private bool m_IsMouseLeftButtonDown;
        private delegate void updateImageDelegate(string tempFile);
        private delegate void OneDoubleArgDelegate(double value);
        private delegate void downloadImageDelegate();
        #region
        public ImageViewer()
        {
            InitializeComponent();
        }
        #endregion


        private void MasterImage_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (image == null)
                return;

            image.ReleaseMouseCapture();
            m_IsMouseLeftButtonDown = false;
        }

        private Point m_PreviousMousePoint;
        private void MasterImage_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (image == null)
                return;

            image.CaptureMouse();
            m_IsMouseLeftButtonDown = true;
            m_PreviousMousePoint = e.GetPosition(MasterImageBorder);
        }

        private void MasterImage_MouseMove(object sender, MouseEventArgs e)
        {
            if (MasterImageBorder == null)
                return;



            if (m_IsMouseLeftButtonDown)
                DoImageMove(MasterImageBorder, e);
        }

        private void DoImageMove(Border border, MouseEventArgs e)
        {
            //Debug.Assert(e.LeftButton == MouseButtonState.Pressed);
            if (e.LeftButton != MouseButtonState.Pressed)
                return;
            this.Cursor = Cursors.Hand;
            Point position = e.GetPosition(border);
            //Trace.WriteLine(e.GetPosition(BackGroundBorder).ToString() + "        " + e.GetPosition(image).ToString() + "      " + e.GetPosition(border).ToString());
            Point imagePosition = image.TransformToVisual(BackGroundBorder).Transform(new Point(0, 0));
            switch ((int)rotateTransform.Angle % 360)
            {
                case 0:
                    if (ImageScrollViewer.ScrollableWidth != 0)
                    {
                        translateTransform.X += position.X - m_PreviousMousePoint.X;
                    }
                    if (ImageScrollViewer.ScrollableHeight != 0)
                    {
                        translateTransform.Y += position.Y - m_PreviousMousePoint.Y;
                    }
                    break;
                case 90:
                    if (ImageScrollViewer.ScrollableWidth != 0)
                    {
                        translateTransform.X += position.Y - m_PreviousMousePoint.Y;
                    }
                    if (ImageScrollViewer.ScrollableHeight != 0)
                    {
                        translateTransform.Y -= position.X - m_PreviousMousePoint.X;
                    }
                    break;
                case 180:
                    if (ImageScrollViewer.ScrollableWidth != 0)
                    {
                        translateTransform.X += position.X - m_PreviousMousePoint.X;
                    }
                    if (ImageScrollViewer.ScrollableHeight != 0)
                    {
                        translateTransform.Y -= position.Y - m_PreviousMousePoint.Y;
                    } break;
                case 270:
                    if (ImageScrollViewer.ScrollableWidth != 0)
                    {
                        translateTransform.X += position.Y - m_PreviousMousePoint.Y;
                    }
                    if (ImageScrollViewer.ScrollableHeight != 0)
                    {
                        translateTransform.Y += position.X - m_PreviousMousePoint.X;
                    }
                    break;
            }
            m_PreviousMousePoint = position;
        }

        private void MasterImage_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            if (Keyboard.IsKeyDown(Key.RightCtrl) || Keyboard.IsKeyDown(Key.LeftCtrl))
            {
                scaleTransform.CenterX = e.GetPosition(MasterImageBorder).X;
                scaleTransform.CenterY = e.GetPosition(MasterImageBorder).Y;
                double newScaleX = scaleTransform.ScaleX + e.Delta * 0.001;
                double newScaleY = scaleTransform.ScaleY + e.Delta * 0.001;
                if (newScaleX > 0)
                {
                    scaleTransform.ScaleX = newScaleX;
                }
                if (newScaleY > 0)
                {
                    scaleTransform.ScaleY = newScaleY;
                }
            }
            else
            {
                if (ImageScrollViewer.ScrollableHeight != 0)
                {
                    if (e.Delta > 0)
                    {
                        ImageScrollViewer.LineUp();
                    }
                    else
                    {
                        ImageScrollViewer.LineDown();
                    }
                }
            }
        }

        public void ReSizeImage()
        {
            scaleTransform.ScaleX = 1.0;
            scaleTransform.ScaleY = 1.0;
            RePositionImage();
        }

        public void RePositionImage()
        {
            translateTransform.X = 0;
            translateTransform.Y = 0;
        }

        public void RotateImage(double angle)
        {
            rotateTransform.CenterX = image.Width / 2;
            rotateTransform.CenterY = image.Height / 2;
            rotateTransform.Angle += angle;
        }

        private void updateimage(string tempFile)
        {
            BinaryReader binReader = new BinaryReader(File.Open(tempFile, FileMode.Open));
            FileInfo fileInfo = new FileInfo(tempFile);
            byte[] bytes = binReader.ReadBytes((int)fileInfo.Length);
            binReader.Close();

            BitmapImage bitmapimage = new BitmapImage();
            bitmapimage.BeginInit();
            bitmapimage.StreamSource = new MemoryStream(bytes);
            bitmapimage.EndInit();
            System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(new MemoryStream(bytes));
            image.Height = bitmapimage.PixelHeight;
            image.Width = bitmapimage.PixelWidth;
            image.Image = bitmap;
            image.Stretch = Stretch.Uniform;
        }

        private void ImageViewer_Loaded(object sender, RoutedEventArgs e)
        {
            if (source != null)
            {
                downloadImageDelegate downloadFetcher = new downloadImageDelegate(downloadImage);
                downloadFetcher.BeginInvoke(null, null);
            }
        }

        private void downloadImage()
        {
            string tempFile = System.IO.Path.GetTempPath();
            tempFile += "bmiddle" + source.Remove(0, source.LastIndexOf('/') + 1);

            double percent = DownloadFile(tempFile, source);
            while (percent != 1.00)
            {
                percent = DownloadFile(tempFile, source);
            }
            image.Dispatcher.BeginInvoke(new updateImageDelegate(updateimage), tempFile);
        }

        private void SetProgressBarValue(double value)
        {
            progressBar.Value = value;
        }

        //实例化流对象
        FileStream FStream;

        public double DownloadFile(string strFileName, string file)
        {
            bool flag = false;
            double percent = 0.00;
            //打开上次下载的文件
            long SPosition = 0;
            //判断要下载的文件夹是否存在
            if (File.Exists(strFileName))
            {
                //打开要下载的文件
                FStream = File.OpenWrite(strFileName);
                //获取已经下载的长度
                SPosition = FStream.Length;
                FStream.Seek(SPosition, SeekOrigin.Current);
            }
            else
            {
                //文件不保存创建一个文件
                FStream = new FileStream(strFileName, FileMode.Create);
                SPosition = 0;
            }
            while (!flag)
            {
                try
                {
                    //打开网络连接
                    HttpWebRequest myRequest = (HttpWebRequest)HttpWebRequest.Create(file);
                    myRequest.Timeout = 5000;
                    if (SPosition > 0)
                        myRequest.AddRange((int)SPosition);             //设置Range值
                    //向服务器请求,获得服务器的回应数据流
                    WebResponse myResponse = myRequest.GetResponse();
                    long length = myResponse.ContentLength;
                    percent = (SPosition * 1.0) / (length * 1.0);
                    progressBar.Dispatcher.BeginInvoke(new OneDoubleArgDelegate(SetProgressBarValue), percent);
                    if (percent == 1.0)
                    {
                        FStream.Close();
                        return percent;
                    }
                    Stream myStream = myResponse.GetResponseStream();
                    //定义一个字节数据
                    byte[] btContent = new byte[512000];
                    int intSize = 0;
                    intSize = myStream.Read(btContent, 0, 512000);
                    while (intSize > 0)
                    {
                        FStream.Write(btContent, 0, intSize);
                        SPosition += intSize;
                        intSize = myStream.Read(btContent, 0, 512000);
                        percent = (SPosition * 1.0) / (length * 1.0);
                        progressBar.Dispatcher.BeginInvoke(new OneDoubleArgDelegate(SetProgressBarValue), percent);
                    }
                    //关闭流
                    FStream.Close();
                    myStream.Close();
                    flag = true;        //返回true下载成功
                }
                catch (Exception ex)
                {
                    flag = false;       //返回false下载失败
                    //percent = SPosition / myStream.Length;
                }
            }
            FStream.Close();
            //return flag;
            return percent;
        }

        private void UserControl_Unloaded(object sender, RoutedEventArgs e)
        {
            if (FStream != null)
            {
                FStream.Close();
            }
        }
    }
}
